import { EDGE_TYPE } from "@/enums/AppTypeEnum";
import { WorkflowIOValueTypeEnum } from "@/enums/WorkflowIOValueTypeEnum";
import { customAlphabet } from 'nanoid';
import { getGlobalVariableNode } from "./adapt";
import { moduleTemplatesFlat } from "@/components/core/workflow/Flow/template/constants";
import { EmptyNode } from "@/components/core/workflow/Flow/template/system/EmptyNode";

export const storeNode2FlowNode = (storeNode:any) => {
    console.log('storeNode2FlowNode',storeNode)

    const template = moduleTemplatesFlat.find((template) => template.flowNodeType == storeNode.flowNodeType) || EmptyNode;

    console.log('storeNode2FlowNode:template',template)
    // replace item data
    const moduleItem:any = {
      ...template,
      ...storeNode,
      avatar: storeNode?.avatar,
      inputs: storeNode.inputs
        .map((storeInput:any) => {
          return {
            ...storeInput
          };
        }),
      outputs: storeNode.outputs.map((storeOutput:any) => {
        return {
          ...storeOutput,
          value: storeOutput.value
        };
      }),
      version: storeNode.version || '481'
    };
    console.log('storeNode2FlowNode:data',{
      id: storeNode.nodeId,
      type: storeNode.flowNodeType,
      data: moduleItem,
      position: storeNode.position || { x: 0, y: 0 }
    })
    return {
      id: storeNode.nodeId,
      type: storeNode.flowNodeType,
      data: moduleItem,
      position: storeNode.position || { x: 0, y: 0 }
    };
  };
  
  export const storeEdgesRenderEdge = ({ edge }: { edge: any }) => {
    return {
      ...edge,
      id: getNanoid(),
      type: EDGE_TYPE
    };
  };

  export const getNanoid = (size = 12) => {
    const firstChar = customAlphabet('abcdefghijklmnopqrstuvwxyz', 1)();
  
    if (size === 1) return firstChar;
  
    const randomsStr = customAlphabet(
      'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890',
      size - 1
    )();
  
    return `${firstChar}${randomsStr}`;
  };

  export const computedNodeInputReference = ({
    nodeId,
    nodes,
    edges,
    chatConfig,
  }:any)=>{
      const node = nodes.find((item:any)=>item.nodeId == nodeId)
      let sourceNodes = [];
      sourceNodes.unshift(
        getGlobalVariableNode({
          nodes,
          chatConfig
        })
      )
      return sourceNodes;
  }


  export const getWorkflowGlobalVariables = ({
    nodes,
    chatConfig,
  }:any)=>{
      const systemVariables = getSystemVariables();
      return [...systemVariables];
  } 
  

  export const nodeTemplate2FlowNode = ({
    template,
    position,
    selected
  }: any) => {
    // replace item data
    const moduleItem = {
     position,
      ...template,
      nodeId: getNanoid()
    };
  
    return {
      id: moduleItem.nodeId,
      type: moduleItem.flowNodeType,
      data: moduleItem,
      position: position,
      selected
    };
  };


  export const getSystemVariables = () => {
    return [
      {
        key: 'appId',
        label: ('common:core.module.http.AppId'),
        required: true,
        valueType: WorkflowIOValueTypeEnum.string
      },
      {
        key: 'chatId',
        label:('common:core.module.http.ChatId'),
        valueType: WorkflowIOValueTypeEnum.string
      },
      {
        key: 'responseChatItemId',
        label:('common:core.module.http.ResponseChatItemId'),
        valueType: WorkflowIOValueTypeEnum.string
      },
      {
        key: 'histories',
        label:('common:core.module.http.Histories'),
        required: true,
        valueType: WorkflowIOValueTypeEnum.chatHistory
      },
      {
        key: 'cTime',
        label: ('common:core.module.http.Current time'),
        required: true,
        valueType: WorkflowIOValueTypeEnum.string
      }
    ];
  };



  export const getHandleId = (nodeId: string, type: 'source' | 'target', key: string) => {
    return `${nodeId}-${type}-${key}`;
  };




  export const storeNodes2RuntimeNodes = (nodes:any,entryNodeIds:any)=>{
        return nodes.map(({data:node}:any)=>{  
          return {
            nodeId: node.nodeId,
            name: node.name,
            avatar: node.avatar,
            intro: node.intro,
            flowNodeType: node.flowNodeType,
            showStatus: node.showStatus,
            isEntry: entryNodeIds.includes(node.nodeId),
            inputs: node.inputs,
            outputs: node.outputs,
            pluginId: node.pluginId
          };
        }) || [];
  }